package org.jeecg.modules.api.service;

import org.apache.commons.io.IOUtils;
import org.apache.commons.net.PrintCommandListener;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.jeecg.modules.paper.entity.PaperLanding;

import java.io.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 列出FTP服务器上指定目录下面的所有文件
 */
public class FTPListAllFilesService {


    public FTPClient ftp;



    /**
     * 重载构造函数
     *
     * @param isPrintCommmand 是否打印与FTPServer的交互命令
     */
    public FTPListAllFilesService(boolean isPrintCommmand) {
        ftp = new FTPClient();
        //arFiles = new ArrayList<String>();
        if (isPrintCommmand) {
            ftp.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));
        }
    }


    /**
     * 登陆FTP服务器
     *
     * @param host     FTPServer IP地址
     * @param port     FTPServer 端口
     * @param username FTPServer 登陆用户名
     * @param password FTPServer 登陆密码
     * @return 是否登录成功
     * @throws IOException
     */
    public boolean login(String host, int port, String username, String password) throws IOException {
        this.ftp.connect(host, port);
        if (FTPReply.isPositiveCompletion(this.ftp.getReplyCode())) {
            if (this.ftp.login(username, password)) {
                /**
                 需要注意这句代码，如果调用List()方法出现，文件的无线递归，与真实目录结构不一致的时候，可能就是因为转码后，读出来的文件夹与正式文件夹字符编码不一致所导致。
                 则需去掉转码，尽管递归是出现乱码，但读出的文件就是真实的文件，不会死掉。等读完之后再根据情况进行转码。
                 如果ftp部署在windows下，则：
                 for (String arFile : f.arFiles) {
                 arFile = new String(arFile.getBytes("iso-8859-1"), "GBK");
                 logger.info(arFile);
                 }
                 */
                this.ftp.setControlEncoding("utf-8");
                return true;
            }
        }
        if (this.ftp.isConnected()) {
            this.ftp.disconnect();
        }
        return false;
    }

    /**
     * 关闭数据链接
     *
     * @throws IOException
     */
    public void disConnection() throws IOException {
        if (this.ftp.isConnected()) {
            this.ftp.disconnect();
        }
    }

    public static String readFileContent(String fileName) {
        File file = new File(fileName);
        BufferedReader reader = null;
        StringBuffer sbf = new StringBuffer();
        try {
            reader = new BufferedReader(new FileReader(file));
            String tempStr;
            while ((tempStr = reader.readLine()) != null) {
                sbf.append(tempStr);
            }
            reader.close();
            return sbf.toString();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }
        return sbf.toString();
    }

    public static void main(String[] args) throws IOException, DocumentException {


        FTPListAllFilesService ftpListAllFiles = new FTPListAllFilesService(true);
        if (ftpListAllFiles.login("106.12.160.17", 21, "root", "Rogerwu19890507!")) {
            //	ftpListAllFiles.List("/aritcle/TrsApp/");
        }
        List<PaperLanding> paperLandingList = new ArrayList<>();
        List<PaperLanding> list = ftpListAllFiles.List("/aritcle/TrsApp/",paperLandingList,true);

        System.out.println(list.size());

    }

    /**
     * 递归遍历目录下面指定的文件名
     *
     * @param pathName 需要遍历的目录，必须以"/"开始和结束
     * @param ext      文件的扩展名
     * @throws IOException
     */
    public void List(String pathName, String ext) throws IOException {
        if (pathName.startsWith("/") && pathName.endsWith("/")) {
            //更换目录到当前目录
            this.ftp.changeWorkingDirectory(pathName);
            FTPFile[] files = this.ftp.listFiles();
            for (FTPFile file : files) {
                if (file.isFile()) {
                    if (file.getName().endsWith(ext)) {
                      //  arFiles.add(pathName + file.getName());
                    }
                } else if (file.isDirectory()) {
                    if (!".".equals(file.getName()) && !"..".equals(file.getName())) {
                        List(pathName + file.getName() + "/", ext);
                    }
                }
            }
        }
    }

    /**
     * 递归遍历出目录下面所有文件
     *
     * @param pathName 需要遍历的目录，必须以"/"开始和结束
     * @throws IOException
     */
    public   List<PaperLanding>  List(String pathName,List<PaperLanding> paperLandingList,Boolean isAll) throws IOException, DocumentException {
       // List<PaperLanding> paperLandingList = new ArrayList<>() ;

        if (pathName.startsWith("/") && pathName.endsWith("/")) {
           // String directory = new String(pathName.getBytes(LOCAL_CHARSET), SERVER_CHARSET);

            //更换目录到当前目录
            this.ftp.changeWorkingDirectory(pathName);
            FTPFile[] files = this.ftp.listFiles();
            String fileName = null;
            for (FTPFile file : files) {

                if(file.isDirectory()){
                    fileName = file.getName();

                }
                if (file.isFile() && file.getName().contains(".xml")) {

                    InputStream inputStream = ftp.retrieveFileStream(pathName + new String(file.getName().getBytes("UTF-8"), "iso-8859-1"));
                 if(inputStream !=null){
                    byte[] bytes = IOUtils.toByteArray(inputStream);
                    //下边两行代码代码只管重要，不然会报空，返回的字节数组，
                    // 调用后再转换成InputStream;inputStream = new ByteArrayInputStream(bytes);

                    SAXReader reader = new SAXReader();
                    Document document = reader.read(new ByteArrayInputStream(new String(bytes).getBytes("UTF-8")));
                    Element root = document.getRootElement();
                    List<Element> childElements = root.elements();
                    String pageName = null;
                    String pageNo = null;
                    for (Element child : childElements) {

                        if (child.getName().equalsIgnoreCase("PageInfo")) {
                            pageName = child.attributeValue("PageName");
                            pageNo = child.attributeValue("PageNo");

                        }
                        if (child.getName().equalsIgnoreCase("ArticleList")) {

                            List<Element> elementList = child.elements();
                            for (Element ele : elementList) {
                                PaperLanding paperLanding = new PaperLanding();

                                if (ele.getName().equalsIgnoreCase("Article")) {
                                    String id = ele.attributeValue("ID");
                                    paperLanding.setId(id);


                                    List<Element> dataList = ele.elements();
                                    for (Element data : dataList) {

                                        if (data.getName().equals("Article")) {
                                            paperLanding.setAuthor(data.getText());
                                        }
                                        if (data.getName().equals("Author")) {
                                            paperLanding.setAuthor(data.getText());
                                        }
                                        if (data.getName().equals("Content")) {
                                            paperLanding.setContent(data.getText().replace("<![CDATA[", "").replace("]]", ""));
                                        }
                                        if (data.getName().equals("Title")) {
                                            paperLanding.setTitle(data.getText().replace("<![CDATA[", "").replace("]]", ""));
                                        }
                                        if (data.getName().equals("SubTitle")) {
                                            paperLanding.setSubtitle(data.getText().replace("<![CDATA[", "").replace("]]", ""));
                                        }
                                        paperLanding.setPagename(pageName);

                                        paperLanding.setPagenum(pageNo);

                                        if (ele.getName().equals("PERIODNUM")) {
                                            paperLanding.setPeriodnum(data.getText());
                                        }
//                                        if (ele.getName().equals("NSID")) {
//                                            paperLanding.setId(ele.getText());
//                                        }
                                        if (ele.getName().equals("NSDATE")) {
                                            paperLanding.setNsid(data.getText());
                                        }

                                    }
                                    paperLanding.setCreateTime(new Date());
                                    String nsid= pathName.replace("/aritcle/TrsApp/","").replace("/","");
                                    paperLanding.setNsid(nsid );
                                    if(nsid != null){
                                        try{
                                            String data  = nsid.substring(0, 4) + "-"
                                                    +nsid.substring(4, 6) + "-"
                                                    +nsid.substring(6, 8);
                                            paperLanding.setPeriodnum(data);
                                        }catch (Exception e){
                                            e.printStackTrace();
                                        }

                                    }

                                    paperLandingList.add(paperLanding);


                                }

                            }

                            inputStream.close();
                            ftp.completePendingCommand();
                        } else if (file.isDirectory()) {
                            // 需要加此判断。否则，ftp默认将‘项目文件所在目录之下的目录（./）’与‘项目文件所在目录向上一级目录下的目录（../）’都纳入递归，这样下去就陷入一个死循环了。需将其过滤掉。
                            if (!".".equals(file.getName()) && !"..".equals(file.getName())) {
                                List(pathName + file.getName() + "/",paperLandingList,isAll);
                            }
                        }
                    }
                 }
                } else if (file.isDirectory()) {
                    // 需要加此判断。否则，ftp默认将‘项目文件所在目录之下的目录（./）’与‘项目文件所在目录向上一级目录下的目录（../）’都纳入递归，这样下去就陷入一个死循环了。需将其过滤掉。
                    if (!".".equals(file.getName()) && !"..".equals(file.getName())) {
                        if(isAll){
                        List(pathName + file.getName() + "/",paperLandingList,true);
                        }
                    }
                }
            }
        }
        return  paperLandingList;
    }
}
